package com.naiterui.ehp.bs.b2c.order.controller;

import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.exception.PublicService;
import com.naiterui.ehp.bp.support.exception.ResponseVO;
import com.naiterui.ehp.bp.support.utils.IpUtil;
import com.naiterui.ehp.bs.b2c.common.util.UserUtils;
import com.naiterui.ehp.bs.b2c.order.exception.OrderExceptionCodes;
import com.naiterui.ehp.bs.b2c.order.service.IOrderService;
import com.naiterui.ehp.bs.b2c.order.vo.OrderInfoVO;
import com.naiterui.ehp.bs.b2c.order.vo.OrderLiteVO;
import com.naiterui.ehp.bs.b2c.order.vo.OrderStatisticalVO;
import com.naiterui.ehp.bs.b2c.order.vo.PlaceOrderParamVO;
import com.naiterui.ehp.bs.b2c.order.vo.PlaceOrderVO;
import com.naiterui.ehp.bs.b2c.order.vo.ShippingInfoVO;
import com.naiterui.ehp.bs.b2c.order.vo.UnifiedOrderResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * <pre>
 *      订单相关
 * </pre>
 *
 * @author 王泽浩
 * @date 2019-05-15 16:09
 * @since 1.0.0
 */
@Validated
@Api(tags = SwaggerTag.PATIENT + SwaggerTag.ORDER)
@RequestMapping("b2c/orders")
@RestController
public class OrderController {

    @Autowired
    private IOrderService orderService;

    private static final Logger LOGGER = LoggerFactory.getLogger(OrderController.class);

    /**
     * 下单请求接口 下单的时候增加价格校验 本接口通过用户ID去查询购物车所有为提交的商品,然后开始计算,并且下单
     *
     * @param placeOrderParamVO 下单请求数据
     */
    @PostMapping
    @ApiOperation(value = "下单请求接口")
    public ResponseVO<PlaceOrderVO> createOrder(@RequestBody @Valid PlaceOrderParamVO placeOrderParamVO) throws BusinessException {
        LOGGER.info("下单请求接口 请求参数：placeOrderParamVO = {}", placeOrderParamVO);
        //开始发票参数校验
        /*InvoiceVO invoice = placeOrderParamVO.getInvoice();
        if (invoice.getIsInvoice() == InvoiceVO.INVOICE_NEED) {
            ValidationUtils.invokeValidatorError(invoice);
        }*/
        PlaceOrderVO placeOrderVO = this.orderService.createOrder(placeOrderParamVO);
        return PublicService.returnResponseVO(placeOrderVO);
    }

    @GetMapping("cancel/{orderId}")
    @ApiOperation(value = "取消订单")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "long", required = true)
    public ResponseVO<Void> cancel(@PathVariable Long orderId) throws BusinessException {
        LOGGER.info("取消订单 请求参数：orderId = {}", orderId);
        Long userId = UserUtils.getUser().getPatientId();
        this.orderService.cancel(userId, orderId);
        return PublicService.returnResponseVO(OrderExceptionCodes.SUCCESS);
    }

    /**
     * 支付接口
     */
    @GetMapping("pay/{orderId}")
    @ApiOperation(value = "支付请求接口")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "long", required = true)
    public ResponseVO<UnifiedOrderResultVO> payOrder(@PathVariable("orderId") Long orderId,
        HttpServletRequest request) throws BusinessException {
        String ip = IpUtil.getIp(request);
        LOGGER.info("支付请求接口 请求参数：orderId = {} ip = {}", orderId, ip);
        UnifiedOrderResultVO unifiedOrderResultVO = this.orderService.payOrder(orderId, ip);
        return PublicService.returnResponseVO(unifiedOrderResultVO);
    }

    /**
     * 订单列表
     */
    @ApiOperation(value = "订单列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "status", value = "订单状态(不传或者0:全部,1:待付款, 2:待发货, 3:待收货, 5:已结束)", paramType = "query", dataType = "int")
    })
    @GetMapping
    public ResponseVO<PageVO<OrderLiteVO>> list(PageParamVO pageParamVO, Integer status) {
        LOGGER.info("订单列表 请求参数：pageParamVO = {}, status = {}", pageParamVO, status);
        Long patientId = UserUtils.getUser().getPatientId();
        PageVO<OrderLiteVO> pageVO = this.orderService.list(pageParamVO, status, patientId);
        return PublicService.returnResponseVO(pageVO);
    }

    @ApiOperation(value = "订单详情", notes = "订单详情(未发货时承运人为空、未支付时支付信息为空、不开发票时发票信息为空)")
    @GetMapping("{orderId}")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "long", required = true)
    public ResponseVO<OrderInfoVO> detail(@PathVariable Long orderId) throws BusinessException {
        LOGGER.info("订单详情 请求参数：orderId = {}", orderId);
        Long patientId = UserUtils.getUser().getPatientId();
        OrderInfoVO orderInfoVO = this.orderService.getOrderDetail(orderId, patientId);
        return PublicService.returnResponseVO(orderInfoVO);
    }

    /**
     * 订单物流信息查询
     */
    @ApiOperation(value = "订单物流", notes = "订单物流(已付款后产生物流)")
    @GetMapping("{orderId}/shipping")
    @ApiImplicitParam(name = "orderId", value = "订单ID", paramType = "path", dataType = "long", required = true)
    public ResponseVO<ShippingInfoVO> shipping(@PathVariable Long orderId) {
        Long userId = UserUtils.getUser().getPatientId();
        ShippingInfoVO shippingInfo = this.orderService.getShippingInfo(orderId, userId);
        return PublicService.returnResponseVO(shippingInfo);
    }

    /**
     * 获取用户订单统计信息
     *
     * @return
     */
    @ApiOperation(value = "获取用户订单统计信息")
    @GetMapping("statisticalInfo")
    public ResponseVO<OrderStatisticalVO> getOrderStatisticalInfo() {
        Long userId = UserUtils.getUser().getPatientId();
        return PublicService.returnResponseVO(orderService.getOrderStatisticalInfo(userId));
    }
}
